/* Copyright 2024 coremail
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { BusinessError } from '@ohos.base';
import http from '@ohos.net.http';
import url from '@ohos.url';
import { Properties } from '../../../api';
import { ExchangeError } from '../error/exchange_error';
import { ModelBase } from '../model/mode_base';
import { RequestBase } from '../request/request_base';
import { ResponseBase } from '../response/response_base';
import httpClient, { HttpRequest } from '../utils/http_client'

/**
 * The abstract class of the Exchange synchronization request task.
 *
 * @param T { T } the request type.
 * @param R { R } the response type.
 * @param TD { TD } the request body type.
 * @param RD { RD } the response body type.
 */
export abstract class TaskBase<T extends RequestBase<TD>, R extends ResponseBase<RD>,
  TD extends ModelBase, RD> {
  protected httpClient: HttpRequest;

  /**
   * 构造器
   *
   * @param { RequestBase } request  请求
   * @param { Properties } properties 属性
   */
  public constructor(protected  request: T, private properties: Properties) {
    this.httpClient = httpClient;
    let requestUrl: url.URL = url.URL.parseURL(properties.exchange.url);
    this.httpClient.setUrl(requestUrl.toString());
  }

  public destroy(): void {
    this.httpClient.destroy();
  };

  /**
   * 执行任务。
   *
   * @returns  {R} 描述exchange响应。
   * @throws { ExchangeError } HttpError http请求异常
   * @throws { ExchangeError } EwsError Exchange业务异常
   * @throws { ExchangeError } HttpError http请求异常
   */
  public abstract execute(): Promise<R>;

  /**
   * 返回http请求是否成功
   *
   * @param { http.HttpResponse } httpResp HTTP响应体
   * @returns 如果为 { true } 成功，否则失败。
   */
  protected isSuccessfully(httpResp: http.HttpResponse): boolean {
    return httpResp.responseCode === http.ResponseCode.OK;
  }

  /**
   * 处理HTTP状态错误。
   *
   * @param httpResp http请求响应体。
   * @returns { ExchangeError } exchange异常实例对象。
   */
  protected handleHttpStatusError(httpResp: http.HttpResponse): ExchangeError<http.HttpResponse> {
    return {
      name: 'HttpError',
      code: httpResp.responseCode,
      data: httpResp,
      message: 'Http request error.',
    };
  }

  /**
   * 处理HTTP请求异常。
   *
   * @param { BusinessError } rawError 原始异常。
   * @returns { ExchangeError } exchange异常实例对象。
   */
  protected handleHttpError(rawError: BusinessError): ExchangeError {
    return {
      name: 'HttpError',
      code: rawError.code,
      stack: rawError.stack,
      message: rawError.message,
    };
  }
}

